
/********************************Copyright (c)**********************************\
**
**                   (c) Copyright 2019, Main, China, QD.
**                           All Rights Reserved
**
**                                 By(wo4fisher)
**                           http://www.wo4fisher.com
**
**----------------------------------文件信息------------------------------------
** 文件名称: ADXL345.c
** 创建人员: wht
** 创建日期: 2019-06-12
** 文档描述:ADXS345加速度传感器模块51库文件
**
**----------------------------------版本信息------------------------------------
** 版本代号: V0.1
** 版本说明: 初始版本
**
**------------------------------------------------------------------------------
\********************************End of Head************************************/
#include "bsp_ADXL345.h"
#include "bsp_delay.h"
#include "zf_pca_delay.h"
#include "math.h"
#include "stdio.h"

#define PI2  57.296    //180/PI

static uint8 idata  buf[8];    //接收数据缓存区
static float mg_x, mg_y, mg_z;

/*******************************************************************************
** 函数名称: ADXL345_Start
** 功能描述: IIC总线启动信号
** 参数说明: : [输入/出][no/no]
** 返回说明: None
** 创建人员: wht
** 创建日期: 2019-06-12
**------------------------------------------------------------------------------
** 修改人员:wht
** 修改日期:
** 修改描述:
**------------------------------------------------------------------------------
********************************************************************************/
static void ADXL345_Start(void)
{
    ADXL345_SDA = 1;                    //拉高数据线
    ADXL345_SCL = 1;                    //拉高时钟线
    delayxus(3);                 //延时
    ADXL345_SDA = 0;                    //产生下降沿
    delayxus(3);                //延时
    ADXL345_SCL = 0;                    //拉低时钟线
}

/*******************************************************************************
** 函数名称: ADXL345_Stop
** 功能描述: IIC总线停止信号
** 参数说明: : [输入/出] [no/no]
** 返回说明: None
** 创建人员: wht
** 创建日期: 2019-06-12
**------------------------------------------------------------------------------
** 修改人员:wht
** 修改日期:
** 修改描述:
**------------------------------------------------------------------------------
********************************************************************************/
static void ADXL345_Stop(void)
{
    ADXL345_SDA = 0;                    //拉低数据线
    ADXL345_SCL = 1;                    //拉高时钟线
    delayxus(3);                //延时
    ADXL345_SDA = 1;                    //产生上升沿
    delayxus(3);                //延时
}

/*******************************************************************************
** 函数名称: ADXL345_SendAck
** 功能描述: 发送应答信号
** 参数说明: ack: [输入](0:ACK 1:NAK)
** 返回说明: None
** 创建人员: wht
** 创建日期: 2019-06-12
**------------------------------------------------------------------------------
** 修改人员:wht
** 修改日期:
** 修改描述:
**------------------------------------------------------------------------------
********************************************************************************/
static void ADXL345_SendAck(bit ack)
{
    ADXL345_SDA = ack;                  //写应答信号
    ADXL345_SCL = 1;                    //拉高时钟线
    delayxus(3);                //延时
    ADXL345_SCL = 0;                    //拉低时钟线
    delayxus(3);                //延时
}

/*******************************************************************************
** 函数名称: ADXL345_RecvAck
** 功能描述: 接收应答信号
** 参数说明: : [输入/出] no
** 返回说明: None
** 创建人员: wht
** 创建日期: 2019-06-12
**------------------------------------------------------------------------------
** 修改人员:wht
** 修改日期:
** 修改描述:
**------------------------------------------------------------------------------
********************************************************************************/
static bit ADXL345_RecvAck(void)
{
    ADXL345_SCL = 1;                    //拉高时钟线
    delayxus(3);                //延时
    CY = ADXL345_SDA;                   //读应答信号
    ADXL345_SCL = 0;                    //拉低时钟线
    delayxus(3);                //延时

    return CY;
}

/*******************************************************************************
** 函数名称: ADXL345_Senduint8
** 功能描述: IIC总线发送一个字节数据
** 参数说明: dat: [输入] 要发送的单字节数据
** 返回说明: None
** 创建人员: wht
** 创建日期: 2019-06-12
**------------------------------------------------------------------------------
** 修改人员:wht
** 修改日期:
** 修改描述:
**------------------------------------------------------------------------------
********************************************************************************/
void ADXL345_SendByte(uint8 dat)
{
    uint8 i;

    for (i = 0; i < 8; i++)     //8位计数器
    {
        dat <<= 1;              //移出数据的最高位
        ADXL345_SDA = CY;               //送数据口
        ADXL345_SCL = 1;                //拉高时钟线
        delayxus(3);            //延时
        ADXL345_SCL = 0;                //拉低时钟线
        delayxus(3);            //延时
    }
    ADXL345_RecvAck();
}

/*******************************************************************************
** 函数名称: ADXL345_Recvuint8
** 功能描述: IIC总线接收一个字节数据
** 参数说明: : [输入/出][no/返回读取到的单字节数据]
** 返回说明: None
** 创建人员: wht
** 创建日期: 2019-06-12
**------------------------------------------------------------------------------
** 修改人员:wht
** 修改日期:
** 修改描述:
**------------------------------------------------------------------------------
********************************************************************************/
uint8 ADXL345_RecvByte(void)
{
    uint8 i;
    uint8 dat = 0;

    ADXL345_SDA = 1;                    //使能内部上拉,准备读取数据,
    for (i = 0; i < 8; i++)     //8位计数器
    {
        dat <<= 1;
        ADXL345_SCL = 1;                //拉高时钟线
        delayxus(3);            //延时
        dat |= ADXL345_SDA;             //读数据
        ADXL345_SCL = 0;                //拉低时钟线
        delayxus(3);            //延时
    }
    return dat;
}

/*******************************************************************************
** 函数名称: single_write_ADXL345
** 功能描述: 单字节写入
** 参数说明: RegAddr: 寄存器地址
**           RegData: 要写入的数据
** 返回说明: None
** 创建人员: wht
** 创建日期: 2019-06-12
**------------------------------------------------------------------------------
** 修改人员:wht
** 修改日期:
** 修改描述:
**------------------------------------------------------------------------------
********************************************************************************/
void single_write_ADXL345(uint8 RegAddr, uint8 RegData)
{
    ADXL345_Start();                  //起始信号
    ADXL345_SendByte(SLAVEADDR);   //发送设备地址+写信号
    ADXL345_SendByte(RegAddr);    //内部寄存器地址，请参考中文pdf22页
    ADXL345_SendByte(RegData);       //内部寄存器数据，请参考中文pdf22页
    ADXL345_Stop();                   //发送停止信号
}

/*******************************************************************************
** 函数名称: single_read_ADXL345
** 功能描述: 单字节读取
** 参数说明: RegAddr:要读取的寄存器地址
** 返回说明: None
**------------------------------------------------------------------------------
** 修改人员:wht
** 修改日期:
** 修改描述:
**------------------------------------------------------------------------------
********************************************************************************/
uint8 single_read_ADXL345(uint8 RegAddr)
{
    uint8 REG_data;
    ADXL345_Start();                          //起始信号
    ADXL345_SendByte(SLAVEADDR);           //发送设备地址+写信号
    ADXL345_SendByte(RegAddr);                   //发送存储单元地址，从0开始

    ADXL345_Start();                          //起始信号
    ADXL345_SendByte(SLAVEADDR + 1);       //发送设备地址+读信号
    REG_data = ADXL345_RecvByte();            //读出寄存器数据
    ADXL345_SendAck(1);
    ADXL345_Stop();                           //停止信号
    return REG_data;
}


/*******************************************************************************
** 函数名称: multiple_read_ADXL345
** 功能描述: 连续读出ADXL345内部加速度数据，地址范围0x32~0x37
** 参数说明: None
** 返回说明: 结果保存在全局变量buf[]中，buf只对本文件可见
** 创建人员: wht
** 创建日期: 2019-06-12
**------------------------------------------------------------------------------
** 修改人员:wht
** 修改日期:
** 修改描述:
**------------------------------------------------------------------------------
********************************************************************************/
void multiple_read_ADXL345(void)
{
    uint8 i;
    ADXL345_Start();                          //起始信号
    ADXL345_SendByte(SLAVEADDR);           //发送设备地址+写信号
    ADXL345_SendByte(0x32);                   //发送存储单元地址，从0x32开始
    ADXL345_Start();                          //起始信号
    ADXL345_SendByte(SLAVEADDR + 1);       //发送设备地址+读信号
    for (i = 0; i < 6; i++)                  //连续读取6个地址数据，存储中BUF
    {
        buf[i] = ADXL345_RecvByte();          //BUF[0]存储0x32地址中的数据
        if (i == 5)
        {
            ADXL345_SendAck(1);                //最后一个数据需要回NOACK
        }
        else
        {
            ADXL345_SendAck(0);                //回应ACK
        }
    }
    ADXL345_Stop();                          //停止信号
    pca_delay_ms(5);
}

/*******************************************************************************
** 函数名称: init_ADXL345
** 功能描述: 初始化ADXL345，根据需要请参考pdf进行修改
** 参数说明: None
** 返回说明: None
**------------------------------------------------------------------------------
** 修改人员:wht
** 修改日期:
** 修改描述:
**------------------------------------------------------------------------------
********************************************************************************/
void init_ADXL345(void)
{
    single_write_ADXL345(0x31, 0x0B);  //测量范围,正负16g，13位模式
    single_write_ADXL345(0x2C, 0x08);  //速率设定为12.5 参考pdf13页
    single_write_ADXL345(0x2D, 0x08);  //选择电源模式   参考pdf24页
    single_write_ADXL345(0x2E, 0x80);  //使能 DATA_READY 中断
    single_write_ADXL345(0x1E, 0x00);  //X 偏移量 根据测试传感器的状态写入pdf29页
    single_write_ADXL345(0x1F, 0x00);  //Y 偏移量 根据测试传感器的状态写入pdf29页
    single_write_ADXL345(0x20, 0x05);  //Z 偏移量 根据测试传感器的状态写入pdf29页
}

/*******************************************************************************
** 函数名称: get_Data_i
** 功能描述: 获取三轴原始数据
** 参数说明: axis: [输入/出]
** 返回说明: None
**------------------------------------------------------------------------------
** 修改人员:wht
** 修改日期:
** 修改描述:
**------------------------------------------------------------------------------
********************************************************************************/
int get_Data_i(uint8 axis)
{
    int temp_data;
    switch (axis)
    {
    case XAXIS:
        temp_data = (buf[1] << 8) + buf[0];
        break;
    case YAXIS:
        temp_data = (buf[3] << 8) + buf[2];
        break;
    case ZAXIS:
        temp_data = (buf[5] << 8) + buf[4];
        break;
    default:
        break;
    }
    return temp_data;

}

/*******************************************************************************
** 函数名称: get_Data_f
** 功能描述: 获取三轴mg单位的数据，所乘的系数需要根据pdf文档和初始化数据格式参数修改
** 参数说明: axis: [输入/出]
** 返回说明: None
** 创建人员: wht
** 创建日期: 2019-06-12
**------------------------------------------------------------------------------
** 修改人员:wht
** 修改日期:
** 修改描述:
**------------------------------------------------------------------------------
********************************************************************************/
float get_Data_f(uint8 axis)
{
    int temp_data;
    temp_data = get_Data_i(axis);

    return ((float)temp_data * 3.9);
}

void get_angle_xy(float * ang_x, float * ang_y)
{
   float temp;
		multiple_read_ADXL345 ();
		mg_x = get_Data_f(XAXIS);
    mg_y = get_Data_f(YAXIS);
    mg_z = get_Data_f(ZAXIS);
    temp = atan2(mg_x, mg_z) * PI2;
	* ang_x = temp;
    temp = atan2(mg_y, mg_z) * PI2;
	* ang_y = temp;
}
/********************************End of File************************************/
